#pragma once
#include "PDTConst.h"
#include "PDTType.h"


#include <map>


class PDTMapConst :  public PDTConst, public PDTNode {
private:
    map<unsigned int, PDTConst *> elements;
public:
    virtual PDTNode * getNode() const {return (PDTNode*) this;}
    virtual PDTConst * getElement(unsigned int i) const {
        map<unsigned int, PDTConst *>::const_iterator it = 
            elements.find(i);
        if (it == elements.end() ) {
            return NULL;
        }
        return it->second;
    }
    virtual unsigned int getSize() const {
        return elements.size();
    }
    virtual void setElement(unsigned int i, PDTConst * el) {
        elements[i] = el;
    }
	virtual NodeTypeEnum getType() { return PDTMapConst_Em;}
	virtual stringstream & toString(stringstream & ss) const {
        map<unsigned int, PDTConst *>::const_iterator it = elements.begin();
        ss << "{";
        for (; it != elements.end(); it++) {
            if (it != elements.begin()) {
                ss << ", ";
            }
            PDTConst * val = it->second;
            PDTNode * node = val->getNode();
            node->toString(ss);
        }
        ss << "}";
        return ss;
    }
	virtual Traversal::RetType traverseEx(Traversal & ){
        //TODO:!
        return Traversal::Continue;
    }

    virtual bool isEqual (const PDTConst & rhs) const {
        if (rhs.getNode() != NULL)
            return false;
        map<unsigned int, PDTConst *>::const_iterator it = elements.begin();
        const PDTMapConst & rhsMap = (const PDTMapConst &)rhs;
        for(;it != elements.end(); it++) {
            unsigned int i = it->first;
            PDTConst * cleft = it->second;
            PDTConst * cright = rhsMap.getElement(i);
            if (cright == cleft) 
                continue;
            if (cright == NULL)
                return false;
            if (*cleft != *cright)
                return false;
        }
        return true;
    }
};
